home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / fileutil.zip / EACCESS.C < prev    next >
C/C++ Source or Header  |  1992-02-22  |  4KB  |  172 lines

  1. /* eaccess -- check if effective user id can access file
  2.    Copyright (C) 1990 Free Software Foundation, Inc.
  3.  
  4.    This program is free software; you can redistribute it and/or modify
  5.    it under the terms of the GNU General Public License as published by
  6.    the Free Software Foundation; either version 1, or (at your option)
  7.    any later version.
  8.  
  9.    This program is distributed in the hope that it will be useful,
  10.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  11.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  12.    GNU General Public License for more details.
  13.  
  14.    You should have received a copy of the GNU General Public License
  15.    along with this program; if not, write to the Free Software
  16.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  17.  
  18. /* David MacKenzie and Torbjorn Granlund */
  19.  
  20. /* MS-DOS port (c) 1990 by Thorsten Ohl, ohl@gnu.ai.mit.edu
  21.    This port is also distributed under the terms of the
  22.    GNU General Public License as published by the
  23.    Free Software Foundation.
  24.  
  25.    Please note that this file is not identical to the
  26.    original GNU release, you should have received this
  27.    code as patch to the official release.
  28.  
  29.    $Header: e:/gnu/fileutil/RCS/eaccess.c 1.4.0.2 90/09/19 12:27:30 tho Exp $
  30.  */
  31.  
  32. #include <sys/types.h>
  33. #include <sys/stat.h>
  34. #ifdef _POSIX_SOURCE
  35. #include <unistd.h>
  36. #else
  37. #ifdef MSDOS
  38. #include <pwd.h>
  39. #else /* not MSDOS */
  40. #include <sys/param.h>
  41. #endif /* not MSDOS */
  42. #endif
  43. #include <errno.h>
  44. #if defined(EACCES) && !defined(EACCESS)
  45. #define EACCESS EACCES
  46. #endif
  47.  
  48. #ifdef MSDOS
  49. #include <stdlib.h>
  50. extern  int eaccess (char *path, int mode);
  51. extern  int eaccess_stat (struct stat *statp, int mode);
  52. #endif /* MSDOS */
  53.  
  54. #ifndef _POSIX_SOURCE
  55. #define F_OK 0
  56. #define X_OK 1
  57. #define W_OK 2
  58. #define R_OK 4
  59. #endif
  60.  
  61. #ifndef STDC_HEADERS
  62. extern int errno;
  63. #endif
  64.  
  65. int eaccess_stat ();
  66.  
  67. /* The user's effective user id. */
  68. static unsigned short euid;
  69.  
  70. /* The user's effective group id. */
  71. static unsigned short egid;
  72.  
  73. /* NGROUPS is defined in sys/param.h on systems with multiple groups. */
  74. #ifdef NGROUPS
  75. static int in_group ();
  76.  
  77. /* Array of group id's that the user is in. */
  78. static unsigned int groups[NGROUPS];
  79.  
  80. /* The number of valid elements in `groups'. */
  81. static int ngroups;
  82. #endif
  83.  
  84. /* Nonzero if the other static variables have valid values. */
  85. static int initialized = 0;
  86.  
  87. /* Return 0 if the user has permission of type MODE on file PATH;
  88.    otherwise, return -1 and set `errno' to EACCESS.
  89.    Like access, except that it uses the effective user and group
  90.    id's instead of the real ones, and it does not check for read-only
  91.    filesystem, text busy, etc. */
  92.  
  93. int
  94. eaccess (path, mode)
  95.      char *path;
  96.      int mode;
  97. {
  98.   struct stat stats;
  99.  
  100.   if (stat (path, &stats))
  101.     return -1;
  102.  
  103.   return eaccess_stat (&stats, mode);
  104. }
  105.  
  106. /* Like eaccess, except that a pointer to a filled-in stat structure
  107.    describing the file is provided instead of a filename. */
  108.  
  109. int
  110. eaccess_stat (statp, mode)
  111.      struct stat *statp;
  112.      int mode;
  113. {
  114.   int granted;
  115.  
  116.   mode &= (X_OK | W_OK | R_OK);    /* Clear any bogus bits. */
  117.  
  118.   if (mode == F_OK)
  119.     return 0;            /* The file exists. */
  120.  
  121.   if (initialized == 0)
  122.     {
  123.       initialized = 1;
  124.       euid = geteuid ();
  125.       egid = getegid ();
  126. #ifdef NGROUPS
  127.       ngroups = getgroups (NGROUPS, groups);
  128. #endif
  129.     }
  130.   
  131.   /* The super-user can read and write any file, and execute any file
  132.      that anyone can execute. */
  133.   if (euid == 0 && ((mode & X_OK) == 0 || (statp->st_mode & 0111)))
  134.     return 0;
  135.   if (euid == statp->st_uid)
  136.     granted = (statp->st_mode & (mode << 6)) >> 6;
  137.   else if (egid == statp->st_gid
  138. #ifdef NGROUPS
  139.        || in_group (statp->st_gid)
  140. #endif
  141.        )
  142.     granted = (statp->st_mode & (mode << 3)) >> 3;
  143.   else
  144.     granted = (statp->st_mode & mode);
  145.   if (granted == mode)
  146.     return 0;
  147.   errno = EACCESS;
  148.   return -1;
  149. }
  150.  
  151. #ifdef NGROUPS
  152. static int
  153. in_group (gid)
  154.      int gid;
  155. {
  156.   int i;
  157.  
  158.   for (i = 0; i < ngroups; i++)
  159.     if (gid == groups[i])
  160.       return 1;
  161.   return 0;
  162. }
  163. #endif
  164.  
  165. #ifdef TEST
  166. main (argc, argv)
  167.      char **argv;
  168. {
  169.   printf ("%d\n", eaccess (argv[1], atoi (argv[2])));
  170. }
  171. #endif
  172.